package top.hkyzf.study.datastructure.linkedlist;

/**
 * 双向链表的实现
 * @author 朱峰
 * @date 2020-12-22 12:59
 */
public class DoubleLinkedList {
    // 初始化一个头节点，不存放具体数据，不要更改头节点
    private HeroNode head = new HeroNode(0, "", "");

    // 添加节点到链表最后
    public void add(HeroNode node) {
        HeroNode temp = head;
        boolean flag = true;
        // 遍历到链表最后一个元素
        while (temp.next != null) {
            if(temp.next.num == node.num) {
                flag = false;
                break;
            }
            temp = temp.next;
        }
        if(flag) {
            temp.next = node;
            node.pre = temp;
        } else {
            System.out.println("要添加的节点已存在，添加失败，节点num为：" + node.num);
        }
    }
    // 按照顺序添加节点
    public void addByOrder(HeroNode node) {
        HeroNode temp = head;
        boolean flag = false;
        // 遍历到链表最后一个元素
        while (true) {
            // 找到最后了
            if(temp.next == null) {
                break;
            }
            // 没有找到最后，但是下一个节点num大于要添加的节点，则需要在当前节点以及下个节点间添加
            if(temp.next.num > node.num) {
                break;
                // 当前节点的下一个节点num等于要添加的节点，则说明已存在，不可添加
            } else if (temp.next.num == node.num) {
                flag = true;
                break;
            }
            // 没有找到最后则temp后移继续循环
            temp = temp.next;
        }
        // 节点已存在，不可添加
        if(flag) {
            System.out.println("要添加的节点已存在，添加失败，节点num为：" + node.num);
        } else {
            node.next = temp.next;
            temp.next = node;
            node.pre = temp;
            // 最后一个节点
            if(temp.next != null) {
                temp.next.pre = node;
            }
        }
    }

    // 按照num更新链表某个节点信息
    public void update(HeroNode node) {
        // 先判断链表是否为空
        if(head.next == null) {
            System.out.println("链表为空，不可修改！");
            return;
        }
        // 由于head节点不可移动，定义一个临时节点
        HeroNode temp = head.next;
        boolean flag = false;
        while (temp != null) {
            // 找到要修改的节点
            if(temp.num == node.num) {
                flag = true;
                break;
            }
            temp = temp.next;
        }
        // 找到要修改的元素了
        if(flag) {
            temp.name = node.name;
            temp.nickName = node.nickName;
        } else {
            System.out.println("没有num为 " + node.num + " 的英雄，修改失败！");
        }
    }

    // 删除链表中的元素
    public void delete(int num) {
        // 先判断链表是否为空
        if(head.next == null) {
            System.out.println("链表为空，不可修改！");
            return;
        }
        // 由于head节点不可移动，定义一个临时节点
        HeroNode temp = head.next;
        boolean flag = false;
        while (temp != null) {
            // 找到了要删除的元素
            if(temp.num == num) {
                flag = true;
                break;
            }
            temp = temp.next;
        }
        if(flag) {
            temp.pre.next = temp.next;
            // 判断是否是最后一个元素
            if(temp.next != null) {
                // 如果是最后一个元素下面的语句不需要执行
                temp.next.pre = temp.pre;
            }
            System.out.println("删除成功了！");
        } else {
            System.out.println("没有num为 " + num + " 的英雄，删除失败！");
        }
    }

    // 列出链表所有元素
    public void list() {
        // 先判断链表是否为空
        if(head.next == null) {
            System.out.println("链表为空，不可修改！");
            return;
        }
        // 由于head节点不可移动，定义一个临时节点
        HeroNode temp = head.next;
        while (temp != null) {
            System.out.println(temp);
            temp = temp.next;
        }
    }

    // 获取head节点
    public HeroNode getHead() {
        return head;
    }
}
